package com.pxl.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pxl.springbootinit.common.ErrorCode;
import com.pxl.springbootinit.exception.BusinessException;
import com.pxl.springbootinit.model.dto.item.ItemLogisticsForm;
import com.pxl.springbootinit.model.entity.Item;
import com.pxl.springbootinit.model.entity.ItemLogistics;
import com.pxl.springbootinit.model.entity.User;
import com.pxl.springbootinit.model.enums.AvailableStatusEnum;
import com.pxl.springbootinit.model.enums.LogisticsStatusEnum;
import com.pxl.springbootinit.model.vo.ItemLogisticsVO;
import com.pxl.springbootinit.service.ItemLogisticsService;
import com.pxl.springbootinit.mapper.ItemLogisticsMapper;
import com.pxl.springbootinit.service.ItemService;
import com.pxl.springbootinit.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author MADAO
* @description 针对表【item_logistics(物品物流状态表)】的数据库操作Service实现
* @createDate 2024-12-20 12:02:23
*/
@Service
public class ItemLogisticsServiceImpl extends ServiceImpl<ItemLogisticsMapper, ItemLogistics>
    implements ItemLogisticsService{

    @Resource
    private ItemService itemService;

    @Resource
    private UserService userService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createLogistics(ItemLogisticsForm itemLogisticsForm, HttpServletRequest request) {
        String receivedAccount = itemLogisticsForm.getReceivedAccount();
        if (itemLogisticsForm == null || itemLogisticsForm.getItemId() == null || receivedAccount == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "请先登录");
        }
        Long itemId = itemLogisticsForm.getItemId();
        Item item = itemService.getById(itemId);
        if (item == null){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "物品不存在");
        }
        User userAccount = userService.getOne(new QueryWrapper<User>().eq("user_account", receivedAccount));
        if (userAccount == null){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "收货人不存在");
        }
        item.setItemType(AvailableStatusEnum.INACTIVE.getValue());
        ItemLogistics itemLogistics = new ItemLogistics();
        BeanUtils.copyProperties(itemLogisticsForm, itemLogistics);
        itemLogistics.setCurrentLocation(loginUser.getAddress());
        itemLogistics.setReceivedId(userAccount.getId());
        if (!(itemService.updateById(item) && this.save(itemLogistics))){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建失败，请重试");
        }

        return true;
    }

    @Override
    public Page<ItemLogisticsVO> pageLogistics(ItemLogisticsForm itemLogisticsForm, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        int current = itemLogisticsForm.getCurrent();
        int pageSize = itemLogisticsForm.getPageSize();
        QueryWrapper<ItemLogistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(itemLogisticsForm.getLogisticsStatus()), "logistics_status", itemLogisticsForm.getLogisticsStatus());
        queryWrapper.like(StringUtils.isNotBlank(itemLogisticsForm.getLogisticsProvider()), "logistics_provider", itemLogisticsForm.getLogisticsProvider());
        queryWrapper.like(StringUtils.isNotBlank(itemLogisticsForm.getTrackingNumber()), "tracking_number", itemLogisticsForm.getTrackingNumber());
        queryWrapper.orderByDesc("updated_time");
        Long userId = loginUser.getId();
        List<Item> itemList = null;
        Page<ItemLogisticsVO> itemLogisticsVOPage = new Page<>();
        QueryWrapper<Item> itemQueryWrapper = new QueryWrapper<>();
        itemQueryWrapper.eq("user_id", userId);
        Page<Item> page = itemService.page(new Page<>(current, pageSize), itemQueryWrapper);
        itemLogisticsVOPage.setTotal(page.getTotal());
        itemLogisticsVOPage.setPages(page.getPages());
        itemList = page.getRecords();
        if (itemList == null || itemList.size() == 0) {
            return new Page<>();
        }
        List<Long> itemIdList = itemList.stream().map(item -> item.getId()).collect(Collectors.toList());
        queryWrapper.in("item_id", itemIdList);

        Page<ItemLogistics> itemLogisticsPage = this.page(new Page<>(current, pageSize), queryWrapper);
        System.out.println(itemLogisticsPage);

        Map<Long, ItemLogistics> logisticsMap = itemLogisticsPage.getRecords().
                stream().collect(Collectors.toMap(itemLogistics -> itemLogistics.getItemId(), itemLogistics -> itemLogistics));

        List<ItemLogisticsVO> itemLogisticsVOList = itemList.stream().map(item -> {
            ItemLogistics itemLogistics = logisticsMap.get(item.getId());
            ItemLogisticsVO itemLogisticsVO = null;
            if (itemLogistics == null) {
                itemLogisticsVO = new ItemLogisticsVO();
                itemLogisticsVO.setItem(item);
            } else {
                itemLogisticsVO = this.getItemLogisticsVO(itemLogistics);
                itemLogisticsVO.setItem(item);
            }
            return itemLogisticsVO;
        }).collect(Collectors.toList());
        itemLogisticsVOPage.setRecords(itemLogisticsVOList);
        return itemLogisticsVOPage;
    }

    @Override
    public ItemLogisticsVO getItemLogisticsVO(ItemLogistics itemLogistics) {
        ItemLogisticsVO itemLogisticsVO = new ItemLogisticsVO();
        BeanUtils.copyProperties(itemLogistics, itemLogisticsVO);
        return itemLogisticsVO;
    }

    @Override
    public List<ItemLogisticsVO> receiveLogisticsList(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        List<ItemLogistics> itemLogisticsList = this.list(
                new QueryWrapper<ItemLogistics>()
                        .eq("received_id", loginUser.getId()));
        List<Long> itemIdList = itemLogisticsList.stream().map(ItemLogistics::getItemId).collect(Collectors.toList());
        Map<Long, Item> logisticsMap = itemService.listByIds(itemIdList).stream().collect(Collectors.toMap(Item::getId, item -> item));

        return itemLogisticsList.stream().map(itemLogistics -> {
            ItemLogisticsVO itemLogisticsVO = this.getItemLogisticsVO(itemLogistics);
            itemLogisticsVO.setItem(logisticsMap.get(itemLogistics.getItemId()));
            return itemLogisticsVO;
        }).collect(Collectors.toList());
    }

    @Override
    public Boolean checkLogistics(Long id, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, "请先登录");
        }
        ItemLogistics itemLogistics = this.getById(id);
        if (itemLogistics == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"物流信息不存在");
        }
        if (loginUser.getId() != itemLogistics.getReceivedId()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"无权操作");
        }
        itemLogistics.setLogisticsStatus(LogisticsStatusEnum.FINISHED.getValue());
        return this.updateById(itemLogistics);
    }

    @Override
    public Page<ItemLogisticsVO> pageLogisticsAdmin(ItemLogisticsForm itemLogisticsForm) {
        int current = itemLogisticsForm.getCurrent();
        int pageSize = itemLogisticsForm.getPageSize();
        QueryWrapper<ItemLogistics> queryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(itemLogisticsForm.getLogisticsStatus())) {
            queryWrapper.or(wq -> wq.eq("logistics_status", itemLogisticsForm.getLogisticsStatus()));
        }

        if (StringUtils.isNotBlank(itemLogisticsForm.getLogisticsProvider())) {
            queryWrapper.or(wq -> wq.like("logistics_provider", itemLogisticsForm.getLogisticsProvider()));
        }

        if (StringUtils.isNotBlank(itemLogisticsForm.getTrackingNumber())) {
            queryWrapper.or(wq -> wq.like("tracking_number", itemLogisticsForm.getTrackingNumber()));
        }
        Page<ItemLogistics> logisticsPage = this.page(new Page<>(current, pageSize), queryWrapper);
        if (CollectionUtils.isEmpty(logisticsPage.getRecords())) {
            return new Page<>();
        }
        List<Long> itemIdList = logisticsPage.getRecords().stream().map(ItemLogistics::getItemId).collect(Collectors.toList());
        Map<Long, Item> itemMap = itemService.listByIds(itemIdList).stream().collect(Collectors.toMap(Item::getId, item -> item));
        List<ItemLogisticsVO> itemLogisticsVOList = logisticsPage.getRecords().stream().map(itemLogistics -> {
            ItemLogisticsVO itemLogisticsVO = this.getItemLogisticsVO(itemLogistics);
            Item item = itemMap.get(itemLogistics.getItemId());
            itemLogisticsVO.setItem(item);
            if (item != null)
                itemLogisticsVO.setName(item.getName());
            return itemLogisticsVO;
        }).collect(Collectors.toList());
        Page<ItemLogisticsVO> itemLogisticsVOPage = new Page<>();
        itemLogisticsVOPage.setRecords(itemLogisticsVOList);
        itemLogisticsVOPage.setTotal(logisticsPage.getTotal());
        itemLogisticsVOPage.setPages(logisticsPage.getPages());
        return itemLogisticsVOPage;
    }

}




